package com.suxin.okhttp.http.builder;

/**
 * @Author: tang
 * @Description:
 * @Date 2024/11/27 14:46
 */

import com.suxin.okhttp.http.core.HttpMethod;
import com.suxin.okhttp.http.core.MediaType;
import com.suxin.okhttp.http.core.request.HttpRequest;
import com.suxin.okhttp.http.core.response.HttpResponse;
import com.suxin.okhttp.http.core.response.OriginalResponse;
import com.suxin.okhttp.http.exception.MalformedMessageException;
import com.suxin.okhttp.http.exception.ServiceException;

import java.io.InputStream;

import static com.suxin.okhttp.http.core.Constant.ACCEPT;
import static java.net.HttpURLConnection.HTTP_MULT_CHOICE;
import static java.net.HttpURLConnection.HTTP_OK;

/** 请求客户端抽象基类 */
public abstract class AbstractHttpClient implements HttpClient {

    @Override
    public <T> HttpResponse<T> execute(HttpRequest httpRequest, Class<T> responseClass) {
        HttpRequest innerRequest =
                new HttpRequest.Builder()
                        .url(httpRequest.getUrl())
                        .httpMethod(httpRequest.getHttpMethod())
                        .headers(httpRequest.getHeaders())
                        .body(httpRequest.getBody())
                        .build();
        OriginalResponse originalResponse = innerExecute(innerRequest);
        validateResponse(originalResponse);
        return assembleHttpResponse(originalResponse, responseClass);
    }

    @Override
    public InputStream download(String url) {
        HttpRequest httpRequest =
                new HttpRequest.Builder()
                        .url(url)
                        .httpMethod(HttpMethod.GET)
                        .addHeader(ACCEPT, "*/*")
                        .build();
        return innerDownload(httpRequest);
    }

    protected abstract InputStream innerDownload(HttpRequest httpRequest);

    protected abstract OriginalResponse innerExecute(HttpRequest httpRequest);

    private void validateResponse(OriginalResponse originalResponse) {

        if (isInvalidHttpCode(originalResponse.getStatusCode())) {
            throw new ServiceException(
                    originalResponse.getRequest(),
                    originalResponse.getStatusCode(),
                    originalResponse.getBody());
        }

        if (originalResponse.getBody() != null
                && !originalResponse.getBody().isEmpty()
                && !MediaType.APPLICATION_JSON.equalsWith(originalResponse.getContentType())) {
            throw new MalformedMessageException(
                    String.format("Unsupported content-type[%s]%nhttpRequest[%s]",
                            originalResponse.getContentType(), originalResponse.getRequest()));
        }
    }

    protected boolean isInvalidHttpCode(int httpCode) {
        return httpCode < HTTP_OK || httpCode >= HTTP_MULT_CHOICE;
    }

    private <T> HttpResponse<T> assembleHttpResponse(
            OriginalResponse originalResponse, Class<T> responseClass) {
        return new HttpResponse.Builder<T>()
                .originalResponse(originalResponse)
                .serviceResponseType(responseClass)
                .build();
    }

    /**
     * 获取http客户端信息，用于User-Agent。 格式：客户端名称/版本 示例：okhttp3/4.9.3
     *
     * @return 客户端信息
     */
    protected abstract String getHttpClientInfo();

}

